package com.qijian.web.controller.common;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qijian.common.constant.CacheKey;
import com.qijian.common.core.domain.AjaxResult;
import com.qijian.common.core.domain.entity.SysDictData;
import com.qijian.common.core.domain.entity.SysMenu;
import com.qijian.common.core.redis.RedisCache;
import com.qijian.common.utils.ObjectUtils;
import com.qijian.common.utils.SecurityUtils;
import com.qijian.common.utils.StringUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.flowable.common.BaseFlowableController;
import com.qijian.flowable.constant.FlowableConstant;
import com.qijian.flowable.service.IFlowableRecordPowerService;
import com.qijian.maindata.service.*;
import com.qijian.system.domain.Dept;
import com.qijian.system.domain.User;
import com.qijian.system.service.*;
import com.qijian.tool.domain.Msg;
import com.qijian.tool.domain.query.MsgQuery;
import com.qijian.tool.service.IMsgService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.TaskService;
import org.flowable.task.api.TaskQuery;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author qijian
 */
@Api(tags = "首页数据")
@RestController
@RequiredArgsConstructor
@RequestMapping("/index")
public class IndexController extends BaseFlowableController {

    private final IUserService userService;
    private final IDeptService deptService;
    private final TaskService taskService;
    private final IFlowableRecordPowerService flowableRecordPowerService;
    private final ISysDictTypeService sysDictTypeService;
     private final ISysMenuService sysMenuService;
    private final RedisCache redisCache;
    private final IMsgService msgService;
    private final IBomService bomService;

    private final IRemindService remindService;




//    @GetMapping("/prompt")
//    public AjaxResult notice() {
//        JSONObject jsonObject = new JSONObject();
//        Long userIdLong = SecurityUtils.getUserId();
//        // 待办事项
//        String userId = userIdLong.toString();
//        TaskQuery query = taskService.createTaskQuery();
//        query.taskCategory(FlowableConstant.CATEGORY_TODO);
//        query.or().taskCandidateOrAssigned(userId).taskOwner(userId).endOr();
//        jsonObject.set("flowable_myToDo", query.count());
//
//        //报修的待办
//        Integer repairTicket = eqpRepairTicketService.selectById(userIdLong);
//        jsonObject.set("repairTicket", repairTicket);
//
//        //保养的待办
//        Integer maintainTicket = eqpMaintainTicketService.selectByOwnerId(userIdLong);
//        jsonObject.set("maintainTicket", maintainTicket);
//
//        //巡检的待办
//        Integer reviewTicket = eqpReviewTicketService.selectById(userIdLong);
//        jsonObject.set("reviewTicket", reviewTicket);
//
//        //备品备件的待办
//        Integer sparePart = eqpSparePartService.selectCount();
//        jsonObject.set("sparePart", sparePart);
//
//        Integer total = repairTicket + maintainTicket + reviewTicket + sparePart;
//        jsonObject.set("eqp_myToDo", total);
//
//        // 待阅事项
//        FlowableRecordPowerQuery powerQuery = new FlowableRecordPowerQuery();
//        powerQuery.setType(FlowableConstant.CC);
//        powerQuery.setIsRead(false);
//        powerQuery.setUserId(userIdLong);
//        long readCount = flowableRecordPowerService.count(WhereEntityTool.invoke(powerQuery));
//        jsonObject.set("flowable_myRead", readCount);
//
//        // 流程管理汇总
//        jsonObject.set("flowable", query.count() + readCount);
//        return AjaxResult.success(jsonObject);
//    }


    private final String LOCK_ADD = "add";
    private final String LOCK_REMOVE = "remove";

    /**
     * 锁定数据
     *
     * @param tableName /
     * @param type      /
     * @param ids       /
     * @return /
     */
    @GetMapping("/locking/{tableName}")
    public AjaxResult locking(@PathVariable String tableName, @RequestParam(value = "type") String type, @RequestParam(value = "ids") List<String> ids) {
        List<String> result = new ArrayList<>(ids.size());
        String key = CacheKey.LOCKING + tableName + "::";
        if (LOCK_ADD.equals(type)) {
            ids.forEach(id -> {
                redisCache.setCacheObject(key + id, id, 10, TimeUnit.MINUTES);
            });
        } else if (LOCK_REMOVE.equals(type)) {
            ids.forEach(id -> redisCache.deleteObject(key + id));
        }
        return AjaxResult.success(result);
    }


    /**
     * 我的
     *
     * @return /
     */
    @GetMapping("/my")
    public AjaxResult my(@RequestParam(value = "userId", required = false) Long userId) {
        Map<String, JSONObject> result = new LinkedHashMap<>();
        List<SysDictData> dictDataList = sysDictTypeService.selectDictDataByType("menu_mgr");
        Map<String, SysDictData> dictDataMap = new HashMap<>(dictDataList.size());
        List<Long> menuIds = new ArrayList<>(dictDataList.size());
        //
        dictDataList.forEach(action -> {
            if (StringUtils.isNotBlank(action.getCssClass())) {
                dictDataMap.put(action.getDictLabel(), action);
                menuIds.add(Long.parseLong(StringUtils.trim(action.getCssClass())));
            }
        });
        // 当前用户
        Long userIdLong = userId == null ? SecurityUtils.getUserId() : userId;
        String userIdStr = userIdLong.toString();

        // 菜单
        List<SysMenu> sysMenuList = sysMenuService.selectMenuList(SecurityUtils.getUserId());
        String menuIdsStr = CollUtil.join(menuIds, ",");
        List<SysMenu> menuList = sysMenuList.stream().filter(action -> action.getShowType().equals("pc") && action.getMenuType().equals("C") && action.getStatus().equals("0") && menuIdsStr.contains(action.getMenuId().toString())).collect(Collectors.toList());
        Map<String, SysMenu> menuMap = new HashMap<>(16);
        Map<String, String> menuParentMap = new HashMap<>(16);
        menuList.forEach(action -> {
            menuMap.put(action.getMenuId() + "", action);
            menuParentMap.put(action.getMenuId() + "", action.getParentId() + "");
        });
//                .collect(Collectors.toMap(a -> a.getMenuId() + "", a -> a))
        String userNickName = "";
        if (userId != null) {
            User user = userService.getById(userId);
            if (user != null) {
                userNickName = user.getNickName();
            }
        } else {
            userNickName = SecurityUtils.getNickName();
        }

        List<Long> deptUserIds = Collections.emptyList();
        List<String> deptUserNickNames = Collections.emptyList();

        List<Dept> list = deptService.list(new LambdaQueryWrapper<Dept>()
                .eq(Dept::getLeaderId, userIdLong)
                .select(Dept::getDeptId));

        if (list.size() > 0) {
            Set<Long> deptIds = list.stream().map(Dept::getDeptId).collect(Collectors.toSet());

            List<User> deptUsers = userService.list(new LambdaQueryWrapper<User>()
                    .in(User::getDeptId, deptIds)
                    .select(User::getUserId, User::getNickName));
            if (deptUsers.size() > 0) {
                deptUserIds = deptUsers.stream().map(User::getUserId).collect(Collectors.toList());
                deptUserNickNames = deptUsers.stream().map(User::getNickName).collect(Collectors.toList());
            }
        }

        // 库存预警
        // 交货计划
        // 商务报价（工艺）
        // 商务报价（采购）
        // 商务报价（物流）
        {
            Map<String, SysDictData> tipMap = new HashMap<>();
            dictDataMap.forEach((key, value) -> {
                if (value.getDictValue().contains("_tip")) {
                    tipMap.put(key, value);
                }
            });

            if (CollUtil.isNotEmpty(tipMap)) {
                MsgQuery msgQuery = new MsgQuery();
                msgQuery.setUserId(userIdLong);
                msgQuery.setIsClose(false);
                tipMap.forEach((key, value) -> {
                    SysMenu menu = null;
                    String[] limitIds = value.getCssClass().split(",");
                    for (String limitId : limitIds) {
                        menu = menuMap.get(limitId);
                        if (ObjectUtils.isNotNull(menu)) {
                            break;
                        }
                    }
                    if (ObjectUtils.isNotNull(menu)) {
                        msgQuery.setSourceType(value.getDictValue());
                        List<Msg> msgList = msgService.list(WhereEntityTool.invoke(msgQuery));
                        setMenu(result, key, msgList.size(), menu, setParamsBySourceIdSet(value.getRemark(), msgList.stream().map(Msg::getSourceId).collect(Collectors.toSet())), menuParentMap);
                    }
                });
            }


        }


        /*
         * 其他
         */
        // 待办事项
        {
            String dbKey = "待办事项";
            TaskQuery query = taskService.createTaskQuery();
            query.taskCategory(FlowableConstant.CATEGORY_TODO);
            query.or().taskCandidateOrAssigned(userIdStr).taskOwner(userIdStr).endOr();
            if (ObjectUtils.isNotNull(dictDataMap.get(dbKey)) && ObjectUtils.isNotNull(menuMap.get(dictDataMap.get(dbKey).getCssClass()))) {
                setMenu(result, dbKey, query.count(), menuMap.get(dictDataMap.get(dbKey).getCssClass()), "{}", menuParentMap);
            }
        }


        return AjaxResult.success(result);
    }

    private String setParamsBySourceId(String remark, String sourceIds) {
        JSONObject params = new JSONObject();
        if (StringUtils.isNotBlank(remark) && JSONUtil.isJson(remark)) {
            params = JSONUtil.parseObj(remark);
            if (StringUtils.isNotBlank(sourceIds)) {
                for (String k : params.keySet()) {
                    if (params.getStr(k).contains("sourceId")) {
                        params.set(k, sourceIds);
                    }
                }
            }
        }
        return JSONUtil.toJsonStr(params);
    }

    private String setParamsBySourceIdSet(String remark, Set<Object> sourceIds) {
        JSONObject params = new JSONObject();
        if (StringUtils.isNotBlank(remark) && JSONUtil.isJson(remark)) {
            params = JSONUtil.parseObj(remark);
            if (ObjectUtils.isNotNull(sourceIds)) {
                for (String k : params.keySet()) {
                    if (params.getStr(k).contains("sourceId")) {
                        params.set(k, CollUtil.join(sourceIds, ","));
                    }
                }
            }
        }
        return JSONUtil.toJsonStr(params);
    }

    private void setMenu(Map<String, JSONObject> result, String key, long count, SysMenu sysMenu, String params, Map<String, String> parentMap) {
        if (count > 0 && sysMenu != null) {
            // 父类红点
            String parentKey = parentMap.get(sysMenu.getMenuId() + "");
            JSONObject child = result.get(parentKey);
            if (ObjectUtils.isNull(child)) {
                child = new JSONObject(2);
                child.set("count", 0);
                child.set("child", new LinkedHashMap<String, JSONObject>());
            }
            LinkedHashMap<String, JSONObject> childList = child.get("child", LinkedHashMap.class);

            JSONObject jsonObject = new JSONObject(3);
            jsonObject.set("count", count);
            jsonObject.set("icon", sysMenu.getIcon());
            jsonObject.set("path", sysMenu.getPath());
            String component = sysMenu.getComponent().substring(0, sysMenu.getComponent().indexOf("/") + 1);
            jsonObject.set("url", String.format("%s%s", component, sysMenu.getPath()));
            jsonObject.set("component", sysMenu.getComponent());
            jsonObject.set("params", params);

            // 数量
            child.set("count", child.getInt("count") + count);
            // 子集
            childList.put(key, jsonObject);
            child.set("child", childList);
            result.put(parentKey, child);
        }
    }
}
